package com.roc.template.cloud.factory.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.roc.template.cloud.CloudConfig;
import com.roc.template.cloud.factory.AccessToken;
import com.roc.template.cloud.util.AccessTokenBean;
import com.roc.template.cloud.util.BasetTokenUtils;
import com.roc.template.cloud.util.HttpClientUtils;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName FileAccessToken
 * @Description: TODO
 * @Author Administrator
 * @Date 2020/7/29 15 02
 * @Version V1.0
 **/
public class FileAccessToken implements AccessToken {

    public String accessToken = null;
    public String refreshToken = null;
    public long expiredUntil = 0L;

    private OkHttpClient client = new OkHttpClient().newBuilder()
            .connectTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .build();


    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    private CloudConfig cloudConfig;

    public FileAccessToken(CloudConfig cloudConfig) {
        this.cloudConfig = cloudConfig;
    }

    @Override
    public void getAccesssToken() {
        JSONObject param = new JSONObject();
        param.put("eid", cloudConfig.eid);
        param.put("secret",cloudConfig.fileSecret);
        param.put("timestamp", System.currentTimeMillis());
        param.put("scope","resGroupSecret");

        String url = cloudConfig.outHost+"/gateway/oauth2/token/getAccessToken";
        String retString = HttpClientUtils.post(url, param.toJSONString());

        JSONObject jsonObject = JSON.parseObject(retString);

        logger.info("获取到accessToken:\n" + jsonObject);
        AccessTokenBean accessTokenBean = BasetTokenUtils.getParam(jsonObject);
        accessToken = accessTokenBean.getAccessToken();
        refreshToken = accessTokenBean.getRefreshToken();
        expiredUntil = accessTokenBean.getExpiredUntil();
    }

    @Override
    public void refreshAccessToken() {
        JSONObject param = new JSONObject();
        param.put("eid", cloudConfig.eid);
        param.put("refreshToken", refreshToken);
        param.put("timestamp", System.currentTimeMillis());
        param.put("scope", "resGroupSecret");

        String url = cloudConfig.outHost+"/gateway/oauth2/token/refreshToken";
        String retString = HttpClientUtils.post(url, param.toJSONString());

        JSONObject jsonObject = JSON.parseObject(retString);
        logger.info("刷新accessToken:\n" + jsonObject);
        AccessTokenBean accessTokenBean = BasetTokenUtils.getParam(jsonObject);
        accessToken = accessTokenBean.getAccessToken();
        refreshToken = accessTokenBean.getRefreshToken();
        expiredUntil = accessTokenBean.getExpiredUntil();
    }

    @Override
    public void checkAndRefreshAccessToken() {
        if (expiredUntil == 0L) {
            getAccesssToken();
        } else if (expiredUntil< 60L) {
            refreshAccessToken();
        }
    }

    /**
     * 文件上传
     * <p>
     * https://yunzhijia.com/cloudflow-openplatform/fileUploadAndDownload/4002
     *
     * @return
     */
    public JSONObject uploadFile(String filePath) {
        checkAndRefreshAccessToken();

        String url =  cloudConfig.outHost+"/docrest/doc/file/uploadfile";
        byte[] bytes;
        try {
            bytes = Files.readAllBytes(Paths.get(filePath));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


        MediaType fileType = MediaType.parse("application/octet-stream");
        RequestBody fileBody = RequestBody.create(fileType, bytes);
        RequestBody body = new MultipartBody.Builder()
                .addFormDataPart("file", filePath, fileBody)
                .addFormDataPart("bizkey", "cloudflow")
                .build();
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .addHeader("content-type", "multipart/form-data")
                .addHeader("Cache-Control", "no-cache")
                .addHeader("x-accessToken", accessToken)
                .build();

        try {
            Response response = client.newCall(request).execute();
            JSONObject jsonObject = JSON.parseObject(response.body().string());
            System.out.println("文件上传\n" + jsonObject);
            return jsonObject;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 文件下载
     * <p>
     * https://yunzhijia.com/cloudflow-openplatform/fileUploadAndDownload/4003
     *
     * @param fileId
     */
    public Response downloadFile(String fileId) {
        checkAndRefreshAccessToken();
        String url =  cloudConfig.outHost+"/docrest/doc/user/downloadfile?bizkey=cloudflow&fileId=";
        url += fileId;

        Request request = new Request.Builder()
                .url(url)
                .get()
                .addHeader("x-accessToken", accessToken)
                .addHeader("Cache-Control", "no-cache")
                .build();

        try {
            Response response = client.newCall(request).execute();
            try (InputStream is = response.body().byteStream();
                 FileOutputStream fos = new FileOutputStream("download.txt")) {
                int length;
                byte[] buf = new byte[2048];
                while ((length = is.read(buf)) != -1) {
                    fos.write(buf, 0, length);
                }
                fos.flush();
            }
            return  response;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
